from django.shortcuts import render_to_response, get_object_or_404
from django.http import Http404, HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User
from models import UserProfile, CouchDBServer
from forms import UserProfileForm, FriendDeleteForm, LoginForm, RegisterForm, ConfirmFriendForm
import datetime
import time
import feedparser
import feedsearcher
import erlydb

def profile(request):
    context = {
        'profile': request.user.get_profile(),
    }
    return render_to_response(
        'simplereg/profile.html',
        context,
        context_instance = RequestContext(request)
    )
profile = login_required(profile)    

def profile_edit(request, profile_id=None):
    if profile_id:
        try:
            profile = get_object_or_404(UserProfile, id=int(profile_id))
        except ValueError:
            raise Http404
        # They shouldn't edit the friend details if the friend is in the system.
        # This might need to turn into a real warning page, maybe not I dunno.
        if profile.user:
            raise Http404
    else:
        profile = request.user.get_profile()
    initial = {
        'feed_url': profile.feed_url,
        'website': profile.website,
    }
    form = UserProfileForm(request.POST or None, profile=profile, initial=initial)
    if form.is_valid():
        form.save()
        if profile_id:
            return HttpResponseRedirect(reverse('sreg_friend_detail', args=(profile_id,)))
        else:
            return HttpResponseRedirect(reverse('sreg_profile'))
    context = {
        'profile': request.user.get_profile(),
        'form': form,
    }
    return render_to_response(
        'simplereg/profile_edit.html',
        context,
        context_instance = RequestContext(request)
    )
profile_edit = login_required(profile_edit)    

def friend_list(request):
    friends = request.user.get_profile().friends.all()
    context = {
        'friend_list': friends,
        'has_friends': friends.count() != 0,
    }
    return render_to_response(
        'simplereg/friend_list.html',
        context,
        context_instance = RequestContext(request)
    )
friend_list = login_required(friend_list)

def friend_detail(request, friend_id):
    try:
        friend_id = int(friend_id)
    except ValueError:
        raise Http404
    context = {
        'friend_profile': get_object_or_404(UserProfile, id=friend_id),
    }
    return render_to_response(
        'simplereg/friend_detail.html',
        context,
        context_instance = RequestContext(request)
    )
friend_detail = login_required(friend_detail)

def friend_add(request):
    up = UserProfile()
    up.save()
    form = UserProfileForm(request.POST or None, profile=up)
    if form.is_valid():
        up = form.save()
        request.user.get_profile().friends.add(up)
        return HttpResponseRedirect(reverse('sreg_friend_list'))
    else:    
        up.delete()
        context = {
            'form': form,
        }
        return render_to_response(
            'simplereg/friend_add.html',
            context,
            context_instance = RequestContext(request)
        )
friend_add = login_required(friend_add)

class FeedItem(object):
    def __init__(self, author, content, link, date_posted):
        self.author = author
        self.content = content
        self.link = link
        self.date_posted = date_posted
    
    # RICH COMPARISON SPECIFICATION
    def __lt__(self, other):
        return self.date_posted < other.date_posted
    
    def __le__(self, other):
        return self.date_posted <= other.date_posted
    
    def __eq__(self, other):
        return self.date_posted == other.date_posted
    
    def __ne__(self, other):
        return self.date_posted != other.date_posted
    
    def __gt__(self, other):
        return self.date_posted > other.date_posted
    
    def __ge__(self, other):
        return self.date_posted >= other.date_posted

def friend_feeds(request):
    feeditem_list = []
    for friend_profile in request.user.get_profile().friends.all():
        fetched = feedparser.parse(friend_profile.feed_url)
        for entry in fetched.entries:
            try:
                dt = datetime.datetime.fromtimestamp(time.mktime(entry.updated_parsed))
                fi = FeedItem(friend_profile, entry.title, entry.link, dt)
                feeditem_list.append(fi)
            except AttributeError, e:
                pass
    feeditem_list.sort(reverse=True)
    context = {
        'feeditem_list': feeditem_list,
        'has_feeds': len(feeditem_list) != 0,
    }
    return render_to_response(
        'simplereg/friend_feeds.html',
        context,
        context_instance = RequestContext(request)
    )
friend_feeds = login_required(friend_feeds)    

def friend_autoadd(request):
    my_website = request.user.get_profile().website
    interface = erlydb.ErlySocialInterface(CouchDBServer.objects.get_url())
    identity_urls = interface.get_identity_urls(my_website)
    if identity_urls:
        identity = True
        friend_list = interface.get_friends(identity_urls)
        feeds = []
        url_cache = {}
        for friend in friend_list:
            friend_urls = interface.get_identity_urls(friend)
            friends_already = False
            for friend_url in friend_urls:
                for already_friend in request.user.get_profile().friends.all():
                    if friend_url == already_friend.website:
                        friends_already = True
            if not friends_already:
                resp = feedsearcher.find_feed_from_sites(friend_urls)
                if resp:
                    (feed, found_from) = resp
                    url_cache[feed] = found_from
                    if feed:
                        feeds.append((feed, friend_urls))
        form = ConfirmFriendForm(request.POST or None, friends=feeds)
        if form.is_valid():
            friends_to_add = []
            for feed_url in form.cleaned_data['friends']:
                website = url_cache[feed_url]
                tmp, created = UserProfile.objects.get_or_create(feed_url=feed_url, website=website)
                friends_to_add.append(tmp)
            request.user.get_profile().friends.add(*friends_to_add)
            return HttpResponseRedirect(reverse('sreg_friend_list'))
    else:
        identity = False
        form = None
        feeds = []
    context = {
        'form': form,
        'has_friends_to_add': len(feeds) != 0,
        'identity': identity,
    }
    return render_to_response(
        'simplereg/friend_autoadd.html',
        context,
        context_instance = RequestContext(request)
    )
friend_autoadd = login_required(friend_autoadd)

def friend_delete(request):
    friends = request.user.get_profile().friends.all()
    form = FriendDeleteForm(request.POST or None, friends=friends)
    if form.is_valid():
        request.user.get_profile().friends.remove(*form.cleaned_data['friends'])
        return HttpResponseRedirect(reverse('sreg_friend_list'))
    context = {
        'form': form,
        'has_friends': friends.count() != 0,
    }
    return render_to_response(
        'simplereg/friend_delete.html',
        context,
        context_instance = RequestContext(request)
    )
friend_delete = login_required(friend_delete)

def login_view(request):
    form = LoginForm(request.POST or None)
    if form.is_valid():
        login(request, form.user)
        return HttpResponseRedirect(request.GET.get('next', reverse('sreg_profile')))
    context = {
        'form': form,
    }
    return render_to_response(
        'simplereg/login.html',
        context,
        context_instance = RequestContext(request)
    )

def register(request):
    form = RegisterForm(request.POST or None)
    if form.is_valid():
        u = User.objects.create_user(
            form.cleaned_data['username'],
            form.cleaned_data['email'],
            form.cleaned_data['password']
        )
        user = authenticate(
            username = form.cleaned_data['username'], 
            password = form.cleaned_data['password']
        )
        login(request, user)
        return HttpResponseRedirect(reverse('sreg_profile'))
    context = {
        'form': form,
    }
    return render_to_response(
        'simplereg/register.html',
        context,
        context_instance = RequestContext(request)
    )
